package com.lcn.core.filter;

import com.lcn.comm.constant.Constants;
import com.lcn.comm.domain.TxTransactionLocal;
import com.weibo.api.motan.common.MotanConstants;
import com.weibo.api.motan.core.extension.Activation;
import com.weibo.api.motan.core.extension.SpiMeta;
import com.weibo.api.motan.filter.Filter;
import com.weibo.api.motan.rpc.*;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;

/**
 * <p>类说明</p>
 *
 * @author 张峰 zfvip_it@163.com
 * @create: 上午9:28
 */
@SpiMeta(name = "transaction")
@Activation(key = {MotanConstants.NODE_TYPE_SERVICE, MotanConstants.NODE_TYPE_REFERER})
public class TransactionFilter implements Filter {

    /**
     * 实现新浪的filter接口 rpc传参数
     *
     * @param caller  caller
     * @param request 请求
     * @return Response
     */
    public Response filter(Caller<?> caller, Request request) {
        TxTransactionLocal txTransactionLocal = TxTransactionLocal.current();
        if (txTransactionLocal != null) {
            request.setAttachment("tx-group", txTransactionLocal.getGroupId());
            if (txTransactionLocal.isHasStart() && !StringUtils.equals(Constants.txManagerInterfaceName, request.getInterfaceName())) {
                hasOnlyNode(caller, txTransactionLocal);
            }
        } else {
            Map<String, String> map = request.getAttachments();
            if (map != null && !map.isEmpty()) {
                if (map.containsKey("tx-group")) {
                    RpcContext.getContext().putAttribute("tx-group", request.getAttachments().get("tx-group"));
                }
            }
        }
        return caller.call(request);
    }

    /**
     * 判断是否同一节点
     *
     * @param caller
     * @param txTransactionLocal
     */
    private void hasOnlyNode(Caller<?> caller, TxTransactionLocal txTransactionLocal) {
        URL url = caller.getUrl();
        String ipPort = url.getHost() + ":" + url.getPort();
        if (!StringUtils.equals(ipPort, txTransactionLocal.getIpPort())) {
            txTransactionLocal.setHasOnlyNode(false);
            TxTransactionLocal.setCurrent(txTransactionLocal);
        }
    }
}
